﻿// Originally contributed by Chinajade.
//
// LICENSE:
// This work is licensed under the
//     Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
// also known as CC-BY-NC-SA.  To view a copy of this license, visit
//      http://creativecommons.org/licenses/by-nc-sa/3.0/
// or send a letter to
//      Creative Commons // 171 Second Street, Suite 300 // San Francisco, California, 94105, USA.

#region Usings

using System;
using System.Linq;
using System.Numerics;
using System.Threading.Tasks;

using Buddy.Coroutines;
using Styx;
using Styx.Pathing;
using Styx.WoWInternals.WoWObjects;
using Styx.CommonBot.Coroutines;
#endregion

namespace Honorbuddy.QuestBehaviorCore
{
    public static partial class UtilityCoroutine
    {
        private static ThrottleCoroutineTask s_mountVehicleUserUpdateThrottle;

        /// <summary>
        /// Mounts a vehicle.
        /// </summary>
        /// <param name="vehicleId">The vehicle identifier.</param>
        /// <param name="searchLocation">The search location.</param>
        /// <param name="movementBy">The movement by.</param>
        /// <param name="extraVehicleQualifiers">The extra vehicle qualifiers.</param>
        /// <returns></returns>
        public static async Task<bool> MountVehicle(
            int vehicleId,
            Vector3 searchLocation,
            MovementByType movementBy = MovementByType.FlightorPreferred,
            Func<WoWUnit, bool> extraVehicleQualifiers = null)
        {
            return await MountVehicle(searchLocation, movementBy, extraVehicleQualifiers, vehicleId);
        }

        /// <summary>
        /// Mounts a vehicle
        /// </summary>
        /// <param name="searchLocation">The search location.</param>
        /// <param name="movementBy">The movement type.</param>
        /// <param name="extraVehicleQualifiers">The extra vehicle qualifiers.</param>
        /// <param name="vehicleIds">The vehicle ids.</param>
        /// <returns>
        ///   <c>true</c> if any action was taken; <c>false</c> otherwise
        /// </returns>
        public static async Task<bool> MountVehicle(
            Vector3 searchLocation,
            MovementByType movementBy = MovementByType.FlightorPreferred,
            Func<WoWUnit, bool> extraVehicleQualifiers = null,
            params int[] vehicleIds)
        {
            if (Query.IsInVehicle())
                return false;

            var vehicle = Query.FindUnoccupiedVehicles(vehicleIds, extraVehicleQualifiers).FirstOrDefault();

            if (vehicle == null)
            {
                if (!Navigator.AtLocation(searchLocation))
                    return await MoveTo(searchLocation, "Vehicle search area", movementBy);

                await
                    (s_mountVehicleUserUpdateThrottle ??
                    (s_mountVehicleUserUpdateThrottle =
                        new ThrottleCoroutineTask(
                            TimeSpan.FromSeconds(10),
                            async () => QBCLog.Info("Waiting for a vehicle to become available"))));
                return true;
            }

            if (!vehicle.WithinInteractRange)
                return await MoveTo(vehicle.Location, vehicle.SafeName, movementBy, vehicle.InteractRange);

            if (await CommonCoroutines.Dismount("Getting inside vehicle"))
                await Coroutine.Sleep(Delay.BeforeButtonClick);
            vehicle.Interact();
            await Coroutine.Sleep(Delay.AfterInteraction);
            return true;
        }
    }
}
